package com.delayqueue.master.netty.handler;

import com.delayqueue.common.netty.handler.*;
import com.delayqueue.master.common.IpTable;
import com.delayqueue.master.config.NettyConfig;
import com.delayqueue.master.netty.handler.inbound.IpFilterHandler;
import com.delayqueue.master.netty.handler.registry.RegistryConnectBootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.ipfilter.RuleBasedIpFilter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MasterServerBootstrap {

    @Autowired
    private NettyConfig nettyConfig;

    @Autowired
    private IpTable ipTable;

    @Autowired
    private RegistryConnectBootstrap registryConnectBootstrap;


    public void init() {
        log.info("master server初始化开始");
        ServerBootstrap bootstrap = new ServerBootstrap();
        bootstrap.group(NettyConfig.boss, NettyConfig.worker);
        bootstrap.channel(NioServerSocketChannel.class);
        bootstrap.handler(new ChannelInitializer<ServerSocketChannel>() {
            @Override
            protected void initChannel(ServerSocketChannel channel) throws Exception {
                channel.pipeline().addLast(new ChannelInboundHandlerAdapter() {
                    @Override
                    public void channelActive(ChannelHandlerContext ctx) throws Exception {
                        log.info("master server启动成功！");
                        registryConnectBootstrap.connect();
                    }
                });
            }
        });
        bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel channel) throws Exception {
                ChannelPipeline pipeline = channel.pipeline();

                pipeline.addLast(new StringToByteEncoder());
                pipeline.addLast(new MessageToStringEncoder());

                if (ipTable.isEnabled()) {
                    IpFilterHandler ipFilterHandler = new IpFilterHandler(ipTable.getWhiteList());
                    pipeline.addLast(new RuleBasedIpFilter(ipFilterHandler));
                }
                pipeline.addLast(new ConnectInboundHandler());
                pipeline.addLast(new ByteToStringDecoder());
                pipeline.addLast(new StringToMessageHandler());
                pipeline.addLast(new MessageInboundHandler());
                pipeline.addLast(new ExceptionHandler());
            }
        });
        bootstrap.bind(nettyConfig.getPort());
    }

}
